<#include "license.ftl">
<@license/>
package ${doc.all.package}.gwt.mvp.service;

import java.util.logging.Logger;

import redora.client.Fields;
import redora.client.Persistable;
import redora.client.Service;
import redora.client.mvp.ClientFactory;
import redora.client.mvp.EditView;
import redora.client.mvp.Locator;
import redora.client.util.ClientUtil;
import redora.client.validation.DefaultMessageAllocator;
import redora.configuration.rdo.gwt.mvp.service.LocatorImplBase;
import redora.configuration.rdo.gwt.model.RedoraConfiguration;
import redora.configuration.rdo.gwt.model.RedoraTrash;
import redora.configuration.rdo.gwt.model.fields.RedoraConfigurationFields;
import redora.configuration.rdo.gwt.model.fields.RedoraTrashFields;
import redora.configuration.rdo.gwt.mvp.util.RedoraConfigurationUtil;
import redora.configuration.rdo.gwt.mvp.util.RedoraTrashUtil;
import redora.configuration.rdo.gwt.mvp.view.RedoraConfigurationEditView;
import redora.configuration.rdo.gwt.mvp.view.RedoraTrashEditView;
import redora.configuration.rdo.gwt.mvp.service.RedoraConfigurationService;
import redora.configuration.rdo.gwt.mvp.service.RedoraTrashService;
import ${doc.all.package}.gwt.constants.MessageAllocator;
import ${doc.all.package}.gwt.model.*;
import ${doc.all.package}.gwt.model.fields.*;
import ${doc.all.package}.gwt.mvp.util.*;
import ${doc.all.package}.gwt.mvp.view.*;

import static java.util.logging.Level.SEVERE;

public class LocatorImpl extends LocatorImplBase {
    static Logger l = Logger.getLogger("LocatorImpl");

    final ClientFactory clientFactory;
    final DefaultMessageAllocator messageAllocator;

<#list doc["/all/object"] as model>
    static ${model.@name}Fields ${model.@name?uncap_first}FieldsInstance;
    static ${model.@name}Util ${model.@name?uncap_first}UtilInstance;
</#list>

    public LocatorImpl(ClientFactory clientFactory) {
        this.clientFactory = clientFactory;
        this.messageAllocator = new MessageAllocator();
    }

    @Override
    public Service locateService(Class<? extends Persistable> cls) {
        if (cls.equals(RedoraTrash.class)) {
            return RedoraTrashService.getInstance();
        } else if (cls.equals(RedoraConfiguration.class)) {
            return RedoraConfigurationService.getInstance();
        }
<#list doc["/all/object"] as model>
          else if (cls.equals(${model.@name}.class)) {
            return ${model.@name}Service.getInstance();
        }
</#list>
        l.log(SEVERE, "Did not find service for " + cls);

        return null;
    }

    @Override
    public ClientUtil locateUtil(Class<? extends Persistable> cls) {
        if (cls.equals(RedoraTrash.class)) {
            if (redoraTrashUtilInstance == null)
                redoraTrashUtilInstance = new RedoraTrashUtil(clientFactory);
            return redoraTrashUtilInstance;
        } else if (cls.equals(RedoraConfiguration.class)) {
            if (redoraConfigurationUtilInstance == null)
                redoraConfigurationUtilInstance = new RedoraConfigurationUtil(clientFactory);
            return redoraConfigurationUtilInstance;
        }
<#list doc["/all/object"] as model>
          else if (cls.equals(${model.@name}.class)) {
            if (${model.@name?uncap_first}UtilInstance == null)
                ${model.@name?uncap_first}UtilInstance = new ${model.@name}Util(clientFactory);
            return ${model.@name?uncap_first}UtilInstance;
        }
</#list>
        l.log(SEVERE, "Did not find util for " + cls);

        return null;
    }

    @Override
    public EditView locateEditView(Class<? extends Persistable> cls) {
        if (cls.equals(RedoraTrash.class)) {
            return new RedoraTrashEditView(cls, clientFactory);
        } else if (cls.equals(RedoraConfiguration.class)) {
            return new RedoraConfigurationEditView(cls, clientFactory);
        }
<#list doc["/all/object"] as model>
          else if (cls.equals(${model.@name}.class)) {
            return new ${model.@name}EditView(cls, clientFactory);
        }
</#list>
        l.log(SEVERE, "Did not find EditView for " + cls);

        return null;
    }

    @Override
    public Fields locateFields(Class<? extends Persistable> cls) {
        if (cls.equals(RedoraTrash.class)) {
            if (redoraTrashFieldsInstance == null)
                redoraTrashFieldsInstance = new RedoraTrashFields();
            return redoraTrashFieldsInstance;
        } else if (cls.equals(RedoraConfiguration.class)) {
            if (redoraConfigurationFieldsInstance == null)
                redoraConfigurationFieldsInstance = new RedoraConfigurationFields();
            return redoraConfigurationFieldsInstance;
        }
<#list doc["/all/object"] as model>
          else if (cls.equals(${model.@name}.class)) {
            if (${model.@name?uncap_first}FieldsInstance == null)
                ${model.@name?uncap_first}FieldsInstance = new ${model.@name}Fields();
            return ${model.@name?uncap_first}FieldsInstance;
        }
</#list>
        l.log(SEVERE, "Did not find fields for " + cls);

        return null;
    }

    @Override
    public Class<? extends Persistable> locateClass(String cls) {
        if (cls.equals("RedoraTrash")) {
            return RedoraTrash.class;
        } else if (cls.equals("RedoraConfiguration")) {
            return RedoraConfiguration.class;
        }
<#list doc["/all/object"] as model>
          else if (cls.equals("${model.@name}")) {
            return ${model.@name}.class;
        }
</#list>
        l.log(SEVERE, "Did not find class " + cls);

        return null;
    }

    @Override
    public DefaultMessageAllocator locateMessage() {
        return messageAllocator;
    }
}